import cv2 as cv
from handutil import HandDetector
import numpy as np


def main():
    # 打开摄像头，0是默认的摄像头索引，如果有多个摄像头，可以通过索引选择
    # 如果在RK3568开发板中运行，需要改为：cap = cv.VideoCapture(9)
    cap = cv.VideoCapture(0)
    # 创建一个手势识别对象
    detector = HandDetector()
    # 6张手的图片，分别代表0～5
    finger_img_list = [
        'fingers/0.png',
        'fingers/1.png',
        'fingers/2.png',
        'fingers/3.png',
        'fingers/4.png',
        'fingers/5.png',
    ]
    finger_list = []
    for fi in finger_img_list:
        i = cv.imread(fi)
        finger_list.append(i)

    # 指尖列表，分别表示大拇指、食指、中指、无名指和小指的指尖
    tip_ids = [4, 8, 12, 16, 20]

    while True:
        # 读取摄像头的下一帧，success是布尔值表示是否成功读取，img是读取到的帧
        success, img = cap.read()
        # 使用cv.flip水平翻转图像，参数1表示进行水平翻转
        # 这通常用于修正摄像头图像的水平翻转问题
        img = cv.flip(img, 1)
        # 检查是否成功读取到帧
        if success:
            # 检测手势
            img = detector.find_hands(img)
            # 获取手势数据
            lmslist = detector.find_positions(img)
            # if len(lmslist) > 0:
            if lmslist is not None and len(lmslist) > 0:
                print('lmslist:', lmslist)
                # print('lmslist.shape:', np.array(lmslist).shape)  # (21, 3)
                fingers = []
                for tid in tip_ids:
                    # 找到每个指尖的位置
                    x, y = lmslist[tid][1], lmslist[tid][2]
                    # 定义三角形的三个顶点
                    size = 5  # 控制三角形大小
                    triangle_pts = np.array([
                        [x, y - size],  # 顶点
                        [x - size, y + size],  # 左下角
                        [x + size, y + size]  # 右下角
                    ], np.int32)
                    # 画实心三角形（红色）
                    cv.fillPoly(img, [triangle_pts], color=(0, 0, 255))
                    # 如果是大拇指，如果大拇指指尖x位置大于大拇指第二关节的位置，则认为大拇指打开，否则认为大拇指关闭
                    if tid == 4:
                        # 根据食指和中指的位置判断左手右手
                        if lmslist[8][1] < lmslist[12][1]:
                            # 右手
                            if lmslist[tid][1] < lmslist[tid - 1][1]:
                                fingers.append(1)
                            else:
                                fingers.append(0)
                        else:
                            # 左手
                            if lmslist[tid][1] > lmslist[tid - 1][1]:
                                fingers.append(1)
                            else:
                                fingers.append(0)
                    # 如果是其他手指，如果这些手指的指尖的y位置大于第二关节的位置，则认为这个手指打开，否则认为这个手指关闭
                    else:
                        if lmslist[tid][2] < lmslist[tid - 2][2]:
                            fingers.append(1)
                        else:
                            fingers.append(0)
                # fingers是这样一个列表，5个数据，0代表一个手指关闭，1代表一个手指打开
                # 判断有几个手指打开
                cnt = fingers.count(1)
                print('cnt:', cnt)
                # 找到对应的手势图片并显示
                finger_img = finger_list[cnt]
                w, h, c = finger_img.shape
                img[0:w, 0:h] = finger_img
            # 显示图像
            cv.imshow('Image', img)
        # 1ms的延迟，等待用户按键操作
        # ord('q')获取字符'q'的ASCII值，用作按键的标识
        k = cv.waitKey(1)
        # 如果用户按下'q'键，则退出循环
        if k == ord('q'):
            break
    # 释放摄像头，释放与之关联的资源
    cap.release()
    # 销毁所有由OpenCV创建的窗口
    cv.destroyAllWindows()


if __name__ == '__main__':
    main()
